package com.didispace.autoconfiguration;

import java.util.ArrayList;
import java.util.List;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.Binding.DestinationType;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.support.postprocessor.DelegatingDecompressingPostProcessor;
import org.springframework.amqp.support.postprocessor.GZipPostProcessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.amqp.RabbitProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.stream.binder.rabbit.RabbitExtendedBindingProperties;
import org.springframework.cloud.stream.config.codec.kryo.KryoCodecAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Primary;
import org.springframework.integration.codec.Codec;
import org.springframework.util.StringUtils;



@Configuration
@AutoConfigureBefore(CachingConnectionFactory.class)
@Import({PropertyPlaceholderAutoConfiguration.class, KryoCodecAutoConfiguration.class})
@EnableConfigurationProperties({MyRabbitBinderConfigurationProperties.class,
	                            RabbitExtendedBindingProperties.class,
	                            RabbitProperties.class})
public class BindExchangeQueueConfiguration {

	@Autowired
	private Codec codec;

	@Autowired
	private ConnectionFactory rabbitConnectionFactory;

	@Autowired
	private RabbitProperties rabbitProperties;

	@Autowired
	private MyRabbitBinderConfigurationProperties rabbitBinderConfigurationProperties;

	@Autowired
	private RabbitExtendedBindingProperties rabbitExtendedBindingProperties;
//	@Autowired
//	DelegatingDecompressingPostProcessor deCompressingPostProcessor;
//	
//	@Autowired
//	MessagePostProcessor messagePostProcessor;
//	
	
	@Bean
	@Primary
	public MyRabbitMessageChannelBinder getBinder(){
		List<MyRabbitMessageChannelBinder>binders =new ArrayList<>();
		String addressesStr = rabbitProperties.getAddresses();
		String[] addresses = StringUtils.commaDelimitedListToStringArray(addressesStr) ;
		com.rabbitmq.client.ConnectionFactory cfs = new com.rabbitmq.client.ConnectionFactory();
	 
		String host = null;
		int port = 0;
		for(String addresse:addresses){
			host = addresse.substring(0, addresse.indexOf(":"));
			port = Integer.parseInt(addresse.substring(addresse.indexOf(":")+1));
			com.rabbitmq.client.ConnectionFactory cf = new com.rabbitmq.client.ConnectionFactory();
			cf.setHost(host);
			cf.setPort(port);
			cf.setUsername(rabbitProperties.getUsername());
			cf.setPassword(rabbitProperties.getPassword());
			CachingConnectionFactory connectionFactory = new CachingConnectionFactory(cf);
			
//			Binding binding = new Binding("bindme.hello",DestinationType.QUEUE,"bindme","#",null);
			GZipPostProcessor gZipPostProcessor = new GZipPostProcessor();
			gZipPostProcessor.setLevel(rabbitBinderConfigurationProperties.getCompressionLevel());
			MyRabbitMessageChannelBinder binder = new MyRabbitMessageChannelBinder(connectionFactory, rabbitProperties);
			binder.setCodec(codec);
			binder.setAdminAddresses(rabbitBinderConfigurationProperties.getAdminAddresses());
			binder.setCompressingPostProcessor(gZipPostProcessor);
			binder.setDecompressingPostProcessor( new DelegatingDecompressingPostProcessor());
			binder.setNodes(rabbitBinderConfigurationProperties.getNodes());
			binder.setExtendedBindingProperties(rabbitExtendedBindingProperties);
			binders.add(binder);
//			try {
//				binder.afterPropertiesSet();
//			} catch (Exception e) {
//			}
//			InputBindingLifecycle inputbinding = new InputBindingLifecycle();
//			inputbinding.start();
		}
		MyRabbitBinder binder = new MyRabbitBinder(rabbitConnectionFactory, rabbitProperties, binders);
		return binder;
	}
}
